package com.yuyou.fn.provider.impl;

import com.github.wens.mybatisplus.examples.Example;
import com.google.common.collect.Collections2;
import com.yuyou.fn.api.StudentService;
import com.yuyou.fn.api.dto.AttendClassRecordDto;
import com.yuyou.fn.api.dto.StudentDto;
import com.yuyou.fn.api.dto.StudentRegDetailDto;
import com.yuyou.fn.api.dto.StudentTimetableDto;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.StudentSaveOrUpdateVo;
import org.apache.commons.lang3.Validate;

import javax.annotation.Resource;
import java.util.*;

public class ExposeStudentServiceImpl implements StudentService {

    @Resource
    private IStudentService studentService;

    @Resource
    private IStudentRegService studentRegService;

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IAttendClassRecordService attendClassRecordService;

    @Resource
    private IAttendClassRecordDetailService attendClassRecordDetailService ;

    @Override
    public Collection<StudentDto> searchByName(String name) {
        Validate.notEmpty(name);
        Example<Student> example = Student.createExample();
        example.createCriteria().andEqualTo("name" ,name );

        List<Student> students = studentService.findListByExample(example);

        if(students == null ){
            return Collections.EMPTY_LIST;
        }

        return Collections2.transform(students, this::toStudentDto);
    }

    @Override
    public StudentDto createStudent(String name, String phoneNo, Integer sex, Long gradeId, String location, String address, String school, Date birthday) {

        Validate.notEmpty(name,"名字可不能为空");
        Validate.notEmpty(phoneNo,"电话号码不能为空");
        Student student = studentService.findByNameAndPhone(name, phoneNo);
        return toStudentDto(studentService.findById(saveOrUpdate(name, phoneNo, sex, gradeId, location, address, school, birthday, student == null ? null : student.getStudentId() )));
    }

    private Long saveOrUpdate(String name, String phoneNo, Integer sex, Long gradeId, String location, String address, String school, Date birthday, Long studentId) {
        StudentSaveOrUpdateVo studentSaveOrUpdateVo = new StudentSaveOrUpdateVo();
        if(studentId != null ){
            studentSaveOrUpdateVo.setStudentId(studentId);
        }
        studentSaveOrUpdateVo.setName(name);
        studentSaveOrUpdateVo.setPhoneNo(phoneNo);
        studentSaveOrUpdateVo.setSex(sex);
        studentSaveOrUpdateVo.setGradeId(gradeId);
        studentSaveOrUpdateVo.setLocation(location);
        studentSaveOrUpdateVo.setAddress(address);
        studentSaveOrUpdateVo.setSchool(school);
        studentSaveOrUpdateVo.setBirthday(birthday);
        return studentService.saveOrUpdateStudent(studentSaveOrUpdateVo);
    }

    @Override
    public void updateStudent(Long studentId, String name, String phoneNo, Integer sex, Long gradeId, String location, String address, String school, Date birthday) {
        saveOrUpdate(name, phoneNo, sex, gradeId, location, address, school, birthday, studentId ) ;
    }

    @Override
    public Collection<StudentRegDetailDto> findStudentReg(Long studentId, Long periodId) {
        Validate.notNull(studentId,"Required studentId");
        Validate.notNull(periodId,"Required periodId");
        List<StudentReg> studentRegs = studentRegService.findStudentRegByPeriodIdStudentId(periodId, studentId);
        if(studentRegs == null ){
            return Collections.EMPTY_LIST;
        }
        List<Long> classIds = BeanUtils.toList(studentRegs,"classId");
        List<CourseClass> courseClasses = courseClassService.findByIds(classIds, CourseClass.BASE_FIELDS);
        Map<Long,CourseClass> classId2CourseClass = BeanUtils.toMap(courseClasses,"classId");
        return Collections2.transform(studentRegs,(sr)->{
            CourseClass courseClass = classId2CourseClass.get(sr.getClassId());
            StudentRegDetailDto studentRegDetailDto = new StudentRegDetailDto() ;
            BeanUtils.copyProperties(studentRegDetailDto,courseClass);
            BeanUtils.copyProperties(studentRegDetailDto,sr);
            return studentRegDetailDto;
        });
    }

    @Override
    public Collection<StudentTimetableDto> findStudentTimetable(Long studentId, Long periodId) {

        Validate.notNull(studentId,"Required studentId");
        Validate.notNull(periodId,"Required periodId");

        Example<AttendClassRecordDetail> example = AttendClassRecordDetail.createExample();
        example.createCriteria().andEqualTo("studentId" , studentId ).andEqualTo("periodId" , periodId ).andIn("shiftStatus" ,Arrays.asList(0,2));

        example.selectProperties("className","lectureNo","startTime" ,"endTime");
        List<AttendClassRecordDetail> attendClassRecordDetails = attendClassRecordDetailService.findListByExample(example);

        if(attendClassRecordDetails == null ){
            return Collections.EMPTY_LIST ;
        }
        return Collections2.transform(attendClassRecordDetails,(ard)->{
            StudentTimetableDto studentTimetableDto = new StudentTimetableDto() ;
            BeanUtils.copyProperties(studentTimetableDto,ard);
            return studentTimetableDto;
        });
    }

    @Override
    public Collection<AttendClassRecordDto> findAttendClassRecordDto(Long regId) {
        Example<AttendClassRecord> example = AttendClassRecord.createExample();
        example.createCriteria().andEqualTo("regId" , regId );
        List<AttendClassRecord> attendClassRecords = attendClassRecordService.findListByExample(example);
        if(attendClassRecords == null ){
            return Collections.EMPTY_LIST;
        }

        return Collections2.transform(attendClassRecords,(acr) ->{
            AttendClassRecordDto attendClassRecordDto = new AttendClassRecordDto();
            BeanUtils.copyProperties(attendClassRecordDto,acr);
            return attendClassRecordDto;
        });
    }

    private StudentDto toStudentDto(Student student) {
        StudentDto studentDto = new StudentDto();
        BeanUtils.copyProperties(studentDto,student);
        return studentDto;
    }
}
